﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Windows.Media.Imaging;

namespace WallpaperCreatorForSamsungPhone
{
    /// <summary>
    /// Represents main page.
    /// </summary>
    public partial class MainPage : UserControl
    {
        public Size PhoneScreenSize { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="MainPage"/> class.
        /// </summary>
        public MainPage()
        {
            this.PhoneScreenSize = new Size(240, 400);

            InitializeComponent();
        }

        /// <summary>
        /// Handles the Drop event of the leftImage control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.DragEventArgs"/> instance containing the event data.</param>
        private void Image_Drop(object sender, DragEventArgs e)
        {
            Image image = (Image)sender;

            if (e.Data != null)
            {
                FileInfo[] files = e.Data.GetData(DataFormats.FileDrop) as FileInfo[];

                if (files != null)
                    LoadImageFromFile(image, files);
            }
        }

        /// <summary>
        /// Loads the image from file.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="files">The files.</param>
        private void LoadImageFromFile(Image image, FileInfo[] files)
        {
            if (image == null)
                throw new ArgumentNullException("image");

            foreach (FileInfo file in files)
            {
                if (file.Exists)
                {
                    try
                    {
                        using (Stream stream = file.OpenRead())
                        {
                            // Decode the image bits
                            BitmapImage bi = new BitmapImage();
                            bi.SetSource(stream);

                            image.Source = bi;

                            // TODO:Set Fit Transform Here

                            break;
                        }
                    }
                    catch (Exception)
                    {
                    }
                }
            }
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is capture mode.
        /// </summary>
        /// <value>
        /// 	<c>true</c> if this instance is capture mode; otherwise, <c>false</c>.
        /// </value>
        private bool IsCaptureMode { get; set; }

        /// <summary>
        /// Gets or sets the offset.
        /// </summary>
        /// <value>The offset.</value>
        private Point CaptureMouseOffset { get; set; }

        /// <summary>
        /// Handles the MouseLeftButtonDown event of the Image control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
        private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //HideTransformWhell();

            // Get Canvas
            UIElement canvas = (UIElement)sender;

            // Process Capture
            canvas.CaptureMouse();
            IsCaptureMode = true;
            CaptureMouseOffset = e.GetPosition(this);

            // Modify Canvas
            canvas.Opacity = 0.7;
            Canvas.SetZIndex(canvas, 1);
        }

        /// <summary>
        /// Handles the MouseLeftButtonUp event of the Image control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
        private void Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (IsCaptureMode)
            {
                // Get Canvas
                ActiveImageControl canvas = (ActiveImageControl)sender;

                // Process Capture
                IsCaptureMode = false;
                canvas.ReleaseMouseCapture();

                // Modify Canvas
                Canvas.SetLeft(canvas, imageStackPanel.Children.IndexOf(canvas)*240);
                Canvas.SetTop(canvas, 0);

                canvas.Opacity = 1;
                Canvas.SetZIndex(canvas, 0);

                foreach (ActiveImageControl testCanvas in new ActiveImageControl[] { leftImage, centerImage, rightImage })
                {
                    if (TryHitTest(testCanvas, e))
                    {
                        SwitchImages(canvas, testCanvas, (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control);
                        break;
                    }
                }
            }
        }

        private void SwitchImages(ActiveImageControl srcImage, ActiveImageControl destImage, bool bCopy)
        {
            if (srcImage != destImage)
            {
                if (bCopy)
                {
                    destImage.Source = srcImage.Source;
                }
                else
                {
                    ImageSource tmpSrc = srcImage.Source;
                    srcImage.Source = destImage.Source;
                    destImage.Source = tmpSrc;
                }
            }
        }

        /// <summary>
        /// Tries the hit test.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
        /// <returns></returns>
        private bool TryHitTest(FrameworkElement element, MouseButtonEventArgs e)
        {
            // Best way is using
            //VisualTreeHelper.FindElementsInHostCoordinates

            Point point = e.GetPosition(element);

            return point.X >= 0 && point.X >= 0 && point.X < element.Width && point.Y < element.Height;
        }

        /// <summary>
        /// Handles the MouseMove event of the Image control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.Input.MouseEventArgs"/> instance containing the event data.</param>
        private void Image_MouseMove(object sender, MouseEventArgs e)
        {
            if (IsCaptureMode)
            {
                // Get Canvas
                UIElement canvas = (UIElement)sender;

                // Process Capture
                Point curPosition = e.GetPosition(this);

                // Modify Canvas
                Canvas.SetLeft(canvas, -CaptureMouseOffset.X + curPosition.X + imageStackPanel.Children.IndexOf(canvas) * 240);
                Canvas.SetTop(canvas, -CaptureMouseOffset.Y + curPosition.Y);
            }
            else
            {
                //ShowTransformWhell(sender);
            }
        }

        //private void ShowTransformWhell(object sender)
        //{
        //    freeTransformWhell.Visibility = System.Windows.Visibility.Visible;
        //    Canvas.SetLeft(freeTransformWhell, Canvas.GetLeft((FrameworkElement)sender) + (((FrameworkElement)sender).Width - freeTransformWhell.Width) / 2);
        //    Canvas.SetTop(freeTransformWhell, Canvas.GetTop((FrameworkElement)sender) + (((FrameworkElement)sender).Height - freeTransformWhell.Height) / 2);
        //}

        private void Image_MouseLeave(object sender, MouseEventArgs e)
        {
           // HideTransformWhell();
        }

        private void btnFullScreen_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;
        }

        /// <summary>
        /// Sets the size of the wallpaper.
        /// </summary>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        private void SetPhoneScreenSize(Size newSize)
        {
            PhoneScreenSize = newSize;

            leftImage.Width = newSize.Width;
            leftImage.Height = newSize.Height;
            centerImage.Width = newSize.Width;
            centerImage.Height = newSize.Height;
            rightImage.Width = newSize.Width;
            rightImage.Height = newSize.Height;

            imageStackPanel.Width = newSize.Width * 3;
            imageStackPanel.Height = newSize.Height;
        }

        private void Border_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            reflectionEffect.ElementHeight = e.NewSize.Height;
        }

        private void btnOpenFile_Click(object sender, RoutedEventArgs e)
        {

        }

        private void btnSaveWallpaper_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Jpeg files|*.jpg|Bmp files|*.bmp|All files|*.*";

            bool? bResault = saveFileDialog.ShowDialog();

            if (bResault.HasValue && bResault.Value)
            {
                using (Stream outputFileStream = saveFileDialog.OpenFile())
                {
                    // Render to WriteableBitmap
                    WriteableBitmap bmp = new WriteableBitmap(imageStackPanel, null);

                    // Encode JPEG and write to FileStream
                    JpegUtils.EncodeJpeg(bmp, outputFileStream);

                    outputFileStream.Flush();
                    outputFileStream.Close();
                }
            }
        }

        private void btnSettings_Click(object sender, RoutedEventArgs e)
        {
            SettingsWindow settings = new SettingsWindow();
            settings.Show();
        }

        //private void HideTransformWhell()
        //{
        //    freeTransformWhell.Visibility = System.Windows.Visibility.Collapsed;
        //}
    }
}
